package mylab.starters.mybatis.utils;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.EnumUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Splitter;
import lombok.experimental.UtilityClass;
import mylab.starters.mybatis.utils.query.OP;
import mylab.starters.mybatis.utils.query.QC;
import mylab.utils.common.DbEscapeUtil;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Objects;

@UtilityClass
public class QueryUtil {
    public boolean existTable(Statement statement, String table) throws SQLException {
        String sql = CharSequenceUtil.format("select count(*) as count from information_schema.tables where table_name = '{}' and table_schema = (select database())", table);
        ResultSet rs = statement.executeQuery(sql);

        rs.next();
        int count = rs.getInt("count");
        return count == 1;
    }

    public boolean existColumn(Statement statement, String table, String column) throws SQLException {
        if (!existTable(statement, table)) {
            return false;
        }

        String sql = CharSequenceUtil.format("select * from {} limit 1", table);

        ResultSet rs = statement.executeQuery(sql);
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();
        // 遍历每一列
        for (int i = 1; i <= columnCount; i++) {
            if (CharSequenceUtil.equals(column, metaData.getColumnName(i))) {
                return true;
            }
        }

        return false;
    }

    /**
     * 根据实体类型与查询条件构造QueryWrapper
     *
     * @param wrapper     QueryWrapper
     * @param QCS         查询条件列表
     * @param entityClass 实体类型
     * @param <T>         泛型
     * @return QueryWrapper
     */
    public <T> QueryWrapper<T> build(QueryWrapper<T> wrapper, List<QC> QCS, Class<T> entityClass) {
        if (QCS == null || QCS.isEmpty()) return wrapper;

        for (QC QC : QCS) {
            Assert.notBlank(QC.getO(), "非法条件");
            Assert.notBlank(QC.getOp(), "非法条件");
            Assert.notNull(QC.getV(), "非法条件");

            String column = MpUtils.getColumnName(entityClass, QC.getO());
            Assert.notBlank(column, "非法条件,无效的字段:" + QC.getO());

            OP op = null;
            try {
                op = EnumUtil.fromString(OP.class, QC.getOp().toUpperCase());
            } catch (Exception ignored) {
            }
            Assert.notNull(op, "非法条件,无效的操作符:" + QC.getOp());

            Object v = QC.getV();
            if (v instanceof CharSequence) {
                //mysql转义符处理
                v = DbEscapeUtil.mysql(v.toString());
            }

            //@formatter:off
            switch (Objects.requireNonNull(op)) {
                case EQ:
                    wrapper.eq(column, v);
                    break;
                case NE:
                    wrapper.ne(column, v);
                    break;
                case GT:
                    wrapper.gt(column, v);
                    break;
                case GE:
                    wrapper.ge(column, v);
                    break;
                case LT:
                    wrapper.lt(column, v);
                    break;
                case LE:
                    wrapper.le(column, v);
                    break;
                //like
                case LK:
                    wrapper.like(column, v);
                    break;
                case LL:
                    wrapper.likeLeft(column, v);
                    break;
                case LR:
                    wrapper.likeRight(column, v);
                    break;
                case NL:
                    wrapper.notLike(column, v);
                    break;
                //between
                case BT:
                    List<String> list = Splitter.on(",").splitToList(v.toString());
                    Assert.isTrue(list.size() == 2, "非法条件,无效的值:" + v);
                    wrapper.between(column, list.get(0), list.get(1));
                    break;
                case NB:
                    list = Splitter.on(",").splitToList(v.toString());
                    Assert.isTrue(list.size() == 2, "非法条件,无效的值:" + v);
                    wrapper.notBetween(column, list.get(0), list.get(1));
                    break;
                case IN:
                    list = Splitter.on(",").splitToList(v.toString());
                    wrapper.in(column, list);
                    break;
                case NI:
                    list = Splitter.on(",").splitToList(v.toString());
                    wrapper.notIn(column, list);
                    break;
                default:
                    break;
            }
            //@formatter:on
        }

        return wrapper;
    }

}
